package com.typhoon.spring_shiro.service.shiro;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.typhoon.spring_shiro.constants.ShiroConstants;
import com.typhoon.spring_shiro.constants.WebConstants;
import com.typhoon.spring_shiro.dto.UserDto;
import com.typhoon.spring_shiro.service.UserService;
import com.typhoon.spring_shiro.utils.GlobalVarGetter;

public class AuthShiroRealm extends AbstractAuthShiroRealm {
	

    private static final Logger LOGGER = LoggerFactory.getLogger(AuthShiroRealm.class);
    
    @Autowired
    private UserService userService;

	/* 
	 * 认证完成组装权限集合
	 * (non-Javadoc)
	 * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// TODO Auto-generated method stub
		LOGGER.info("认证完成回调进行授权:{}",JSON.toJSONString(principals));
		
        // 获取当前登录的用户名
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Session session = SecurityUtils.getSubject().getSession();
        authorizationInfo.setRoles((Set<String>) session.getAttribute(ShiroConstants.ROLES));
        authorizationInfo.setStringPermissions((Set<String>) session.getAttribute(ShiroConstants.PERMISSIONS));
        return authorizationInfo;
	}

	/* 
	 * 认证
	 * (non-Javadoc)
	 * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		LOGGER.info("身份认证:{}",JSON.toJSONString(authcToken));
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = token.getUsername();
		String password = String.valueOf(token.getPassword());
		Session session = SecurityUtils.getSubject().getSession();
        // 提前获取权限信息并存放入session，防止第一次登录时没有菜单的问题
		UserDto user = new UserDto();
		user.setId(1l);
		session.setAttribute("user", user);
        loadAuthorizationInfo(username, null);
        return new SimpleAuthenticationInfo(username,password, null, getName());
	}
	
    private void loadAuthorizationInfo(String username, String userType) {

        Session session = SecurityUtils.getSubject().getSession();
    	UserDto user = GlobalVarGetter.getUser();
    	if(null == user) {
    		LOGGER.warn("用户名:{}在session中的信息丢失",username);
    		return;
    	}
    	Map<String,Collection> authorizationMap = userService.getAuthorizationInfo(user.getId());

//        ShopAccount shopAccount = SessionUtils.getShopAccount();
//        Shop shop = SessionUtils.getShop();
//
//        if (null == shopAccount || null == shop) {
//            LOGGER.warn("用户名：{} 在session中的信息丢失!", username);
//        }
//        Map<String, Collection> authorizationMap = shopAccountService.getAuthorizationInfo(username, userType, shopAccount,
//            shop);
//        
//        List<Menu> menuList = (List<Menu>) authorizationMap.get(SYS_MENU_LIST);
//        session.setAttribute(SYS_MENU_LIST, menuList);
//        session.setAttribute(PERMISSIONS, authorizationMap.get(PERMISSIONS)); // 设置权限
//        session.setAttribute(ROLES, authorizationMap.get(ROLES));// 设置角色
//        session.setAttribute(APPS, authorizationMap.get(APPS));
    	session.setAttribute(ShiroConstants.APPS, authorizationMap.get(ShiroConstants.APPS));
    	session.setAttribute(ShiroConstants.ROLES, authorizationMap.get(ShiroConstants.ROLES));
    	session.setAttribute(ShiroConstants.PERMISSIONS, authorizationMap.get(ShiroConstants.PERMISSIONS));
    }
    
    private void loginErrorCount(Session session) {
        Object loginErrorCount = session.getAttribute(WebConstants.LOGIN_ERROR_COUNT);
        if (loginErrorCount == null) {
            loginErrorCount = 1;
        } else {
            loginErrorCount = Integer.parseInt(loginErrorCount.toString()) + 1;
        }
        session.setAttribute(WebConstants.LOGIN_ERROR_COUNT, loginErrorCount);
    }

}
